/*
 * keys.cpp
 *
 *  Created on: 12.02.2012
 *      Author: Roma Jam
 */

#include "stm32f10x_gpio.h"
#include "delay_util.h"
#include "keys.h"
#include "fulfilment.h"

void keys_t::Init(void) {
    RCC_APB2PeriphClockCmd(BTN_CLK, ENABLE);
    GPIO_InitTypeDef  GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = BTN_1 | BTN_2 | BTN_3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(BTN_GPIO_PORT, &GPIO_InitStructure);
} // Init

void keys_t::Task(void) {
    enum key_name_t Key_press;
    Key_press = None;
    if (!Delay.Elapsed(&key.timer, 50)) {
        key.key_is_press = false;
        return;
    }
    IO_Switch(BTN_a, BTN_b, BTN_c);
    Enable_first_line_buttns();
    key.string_of_key = 1;
    Key_press = Check_Keypressed(key.string_of_key);
    Disable_first_line_buttns();
    if ((Key_press != None) && (!key.key_is_press)) {
        key.key_is_press = true;
        Delay.Reset(&key.timer);
        Event_Keypressed(Key_press);
    } else {
        if (Key_press == None) {
            Event_Keypressed(Key_press);
            key.key_is_press = false;
        }
    }
    IO_Switch(BTN_b, BTN_a, BTN_c);
    Enable_second_line_buttns();
    key.string_of_key = 2;
    Key_press = Check_Keypressed(key.string_of_key);
    Disable_second_line_butts();
    if ((Key_press != None) && (!key.key_is_press)) {
        key.key_is_press = true;
        Delay.Reset(&key.timer);
        Event_Keypressed(Key_press);
    } else {
        if (Key_press == None) {
            Event_Keypressed(Key_press);
            key.key_is_press = false;
        }
    }
    IO_Switch(BTN_c, BTN_b, BTN_a);
    Enable_third_line_buttns();
    key.string_of_key = 3;
    Key_press = Check_Keypressed(key.string_of_key);
    Disable_third_line_buttns();
    if ((Key_press != None) && (!key.key_is_press))  {
        key.key_is_press = true;
        Delay.Reset(&key.timer);
        Event_Keypressed(Key_press);
    } else {
        if (Key_press == None) {
            Event_Keypressed(Key_press);
            key.key_is_press = false;
        }
    }
} // Task

void keys_t::IO_Switch(uint16_t Pin1, uint16_t Pin2, uint16_t Pin3) {
    RCC_APB2PeriphClockCmd(BTN_CLK, ENABLE);
    GPIO_InitTypeDef  GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = Pin1;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(BTN_GPIO_PORT, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = Pin2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(BTN_GPIO_PORT, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = Pin3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(BTN_GPIO_PORT, &GPIO_InitStructure);
} // IO_Switch

key_name_t keys_t::Check_Keypressed(uint8_t Check_value) {
    enum key_name_t Now_press;
    if (Check_value !=0) {
        if (Check_value == 1) {
            if (BTN1_IS_PRESSED()) return Now_press = F1;
            else if (BTN2_IS_PRESSED()) return Now_press = F2;
            else if (BTN3_IS_PRESSED()) return Now_press = F3;
        } // String 1
        else
        if (Check_value == 2) {
            if (BTN1_IS_PRESSED()) return Now_press = Left;
            else if (BTN2_IS_PRESSED()) return Now_press = Up;
            else if (BTN3_IS_PRESSED()) return Now_press = Right;
        } // String 2
        else
        if (Check_value == 3) {
            if (BTN1_IS_PRESSED()) return Now_press = Stop;
            else if (BTN2_IS_PRESSED()) return Now_press = Down;
            else if (BTN3_IS_PRESSED()) return Now_press = Start;
        } // String 3
    }
    return Now_press = None;
} // Check_Keypressred

void keys_t::Event_Keypressed(key_name_t Value_of_Key) {
    switch(Value_of_Key) {
        case None: {
            Execute.None();
        } break;
        case F1: {
            Execute.F1();
        } break;
        case F2: {
            Execute.F2();
        } break;
        case F3: {
            Execute.F3();
        } break;
        case Left: {
            Execute.Left();
        } break;
        case Up: {
            Execute.Up();
        } break;
        case Right: {
            Execute.Right();
        } break;
        case Stop: {
            Execute.Stop();
        } break;
        case Down: {
            Execute.Down();
        } break;
        case Start: {
            Execute.Start();
        } break;
        case Error: {

        } break;
        default: {

        } break;
    }
}
